home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
xinu.arc
/
XINUC2.C
< prev
next >
Wrap
Text File
|
1986-01-03
|
11KB
|
463 lines
/* mark.c - _mkinit, mark p. 232 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# ifdef MEMMARK
int *marks[MAXMARK];
int nmarks;
int mkmutex;
/*-----------------------------------------------------------------------------
* _mkinit -- called once at system startup
*-----------------------------------------------------------------------------
*/
_mkinit()
{
mkmutex = screate(1);
nmarks = 0;
}
/*-----------------------------------------------------------------------------
* mark -- mark a location if it hasn't been marked
*-----------------------------------------------------------------------------
*/
mark(loc)
int *loc;
{
if (*loc>=0 && *loc<nmarks && marks[*loc]==loc)
return(0);
if (nmarks>=MAXMARK)
return(SYSERR);
wait(mkmutex);
marks[(*loc) = nmarks++] = loc;
signal(mkmutex);
return(OK);
}
# endif
/* memread.c */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* memread -- read a block from the 'memory' device
*-----------------------------------------------------------------------------
*/
memread(devptr, buff, block)
struct devsw *devptr;
char *buff;
DBADDR block;
{
char *addr;
int cnt;
/* convert block number into byte address by multiplying 'block'
by DBUFSIZ. Be careful with this computation, since the
effect of multiplying block by DBUFSIZ with result in a
long. So we first convert block to a long to allow the
multiplication to work. If you did the multiplication first,
then the casting you would get an integer extended to a long.
This just doesn't work. There also isn't any checking for
out of range. */
addr = (char *)((long)block * DBUFSIZ);
/* copy the data to the user's buffer area */
è for( cnt = DBUFSIZ; cnt--; ) *buff++ = *addr++;
return(OK);
}
/* memwrite.c */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* memwrite -- write a block to the 'memory' device
*-----------------------------------------------------------------------------
*/
memwrite(devptr, buff, block)
struct devsw *devptr;
char *buff;
DBADDR block;
{
char *addr;
int cnt;
/* see comment in memread. */
addr = (char *)((long)block * DBUFSIZ);
/* copy the data from the user's buffer area */
for( cnt = DBUFSIZ; cnt--; ) *addr++ = *cnt++;
return(OK);
}
/* mkpool.c - mkpool p. 238 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# include <bufpool.h>
/*-----------------------------------------------------------------------------
* mkpool -- allocate memory for a buffer pool and link together
*-----------------------------------------------------------------------------
*/
mkpool(bufsiz, numbufs)
int bufsiz, numbufs;
{
char ps;
int poolid;
char *where;
# ifdef MEMMARK
if (unmarked(bpmark))
poolinit();
# endif
disable(ps);
if (bufsiz<BPMINB || bufsiz>BPMAXB
|| numbufs<1 || numbufs>BPMAXN
|| nbpools>=NBPOOLS
|| (where=getmem((bufsiz+sizeof(int))*numbufs)) == SYSERR) {
restore(ps);
return(SYSERR);
}
poolid = nbpools++;
bptab[poolid].bpnext = where;
bptab[poolid].bpsize = bufsiz;
bptab[poolid].bpsem = screate(numbufs);
bufsiz += sizeof(int);
for (numbufs-- ; numbufs>0 ; numbufs--, where+=bufsiz)
*((int *)where) = (int)(where + bufsiz);
*((int *)where) = (int)NULL;
restore(ps);
return(poolid);
}
/* newqueue.c - newqueue p. 50 */
# include <conf.h>
# include <kernel.h>
# include <q.h>
/*-----------------------------------------------------------------------------
* newqueue -- initialize a new list in the q structure
*-----------------------------------------------------------------------------
*/
int newqueue()
{
struct qent *hptr; /* address of new list head */
struct qent *tptr; /* address of new list tail */
int hindex, tindex; /* head and tail indexes */
hptr = &q[hindex=nextqueue++]; /* nextqueue is global variable */
tptr = &q[tindex=nextqueue++]; /* giving next used q pos. */
hptr->qnext = tindex;
hptr->qprev = EMPTY;
hptr->qkey = MININT;
tptr->qnext = EMPTY;
tptr->qprev = hindex;
tptr->qkey = MAXINT;
return(hindex);
}
/* open.c - open p. 150 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
/*-----------------------------------------------------------------------------
* open -- open a connection to a device/file (params 2&3 are optional)
*-----------------------------------------------------------------------------
*/
open(descrp, nam, mode)
int descrp;
char *nam, *mode;
{
struct devsw *devptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
return ((*devptr->dvopen)(devptr,nam,mode));
}
/* pcreate.c - pcreate p. 244 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# include <ports.h>
/*-----------------------------------------------------------------------------
* pcreate -- create a port thet allows "count" outstanding messages
*-----------------------------------------------------------------------------
*/
SYSCALL pcreate(count)
int count;
{
char ps;
int i, p;
struct pt *ptptr;
if (count < 0)
return(SYSERR);
disable(ps);
# ifdef MEMMARK
if (mark(ptmark) == OK)
pinit(MAXMSGS);
# endif
for (i=0 ; i<NPORTS ; i++) {
if ((p=ptnextp--) <= 0)
ptnextp - NPORTS - 1;
if ((ptptr=&ports[p])->ptstate == PTFREE) {
ptptr->ptstate = PTALLOC;
ptptr->ptssem = screate(count);
ptptr->ptrsem = screate(0);
ptptr->pthead = ptptr->pttail = NULL;
ptptr->ptseq++;
ptptr->ptmaxcnt = count;
restore(ps);
return(p);
}
}
restore(ps);
return(SYSERR);
}
/* pdelete.c - pdelete p. 250 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# include <ports.h>
/*-----------------------------------------------------------------------------
* pdelete -- delete a port, freeing waiting processes and messages
*-----------------------------------------------------------------------------
*/
SYSCALL pdelete(portid, dispose)
int portid;
int (*dispose)();
{
char ps;
struct pt *ptptr;
disable(ps);
if (isbadport(portid) ||
# ifdef MEMMARK
unmarked(ptmark) ||
# endif
(ptptr=&ports[portid])->ptstate != PTALLOC) {
restore(ps);
return(SYSERR);
}
_ptclear(ptptr, PTFREE, dispose);
restore(ps);
return(OK);
}
/* pinit.c - pinit p. 243 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# include <ports.h>
# ifdef MEMMARK
MARKER ptmark;
# endif
struct ptnode *ptfree; /* list of free queue nodes */
struct pt ports[NPORTS];
int ptnextp;
/*-----------------------------------------------------------------------------
* pinit -- initialize all ports
*-----------------------------------------------------------------------------
*/
SYSCALL pinit(maxmsgs)
int maxmsgs;
{
int i;
struct ptnode *next, *prev;
if ((ptfree=getmem(maxmsgs*sizeof(struct ptnode))) == SYSERR)
panic ("pinit - insufficient memory");
for (i=0 ; i<NPORTS ; i++)
ports[i].ptstate = PTFREE;
ptnextp = NPORTS - 1;
/* link up free list of message pointer nodes */
for (prev=next=ptfree ; --maxmsgs>0 ; prev=next)
prev->ptnext = ++next;
prev->ptnext = NULL;
return(OK);
}
/* poolinit.c - poolinit p. 240 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# include <bufpool.h>
struct bpool bptab[NBPOOLS];
int nbpools;
# ifdef MEMMARK
MARKER bpmark; /* self initializing mark */
# endif
/*-----------------------------------------------------------------------------
* poolinit -- initialize the buffer pool routines
*-----------------------------------------------------------------------------
*/
poolinit()
{
# ifdef MEMMARK
int status;
char ps;
disable(ps);
if ((status=mark(bpmark)) == OK) {
nbpools = 0;
}
restore(ps);
return((status==OK) ? OK : SYSERR);
# else
nbpools = 0;
return(OK);
# endif
}
/* preceive.c - preceive p. 248 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# include <ports.h>
/*-----------------------------------------------------------------------------
* preceive -- receive a message from a port, blocking if port empty
*-----------------------------------------------------------------------------
*/
SYSCALL preceive(portid)
int portid;
{
char ps;
struct pt *ptptr;
int seq;
int msg;
struct ptnode *nxtnode;
disable(ps);
if (isbadport(portid) ||
# ifdef MEMMARK
unmarked(ptmark) ||
# endif
(ptptr=&ports[portid])->ptstate != PTALLOC) {
restore(ps);
return(SYSERR);
}
/* wait for message and verify that the port is still allocated */
seq = ptptr->ptseq;
if (wait(ptptr->ptrsem) == SYSERR || ptptr->ptstate != PTALLOC
|| ptptr->ptseq != seq) {
restore(ps);
return(SYSERR);
}
/* dequeue first message that is waiting in the port */
nxtnode = ptptr->pthead;
msg = nxtnode->ptmsg;
if (ptptr->pthead == ptptr->pttail) /* delete last item */
ptptr->pthead = ptptr->pttail = NULL;
else
ptptr->pthead = nxtnode->ptnext;
nxtnode->ptnext = ptfree; /* return to free list */
ptfree = nxtnode;
signal(ptptr->ptssem);
restore(ps);
return(msg);
}
/* psend.c - psend p. 245 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# include <ports.h>
/*-----------------------------------------------------------------------------
* psend -- send a message to a port by enqueuing it
*-----------------------------------------------------------------------------
*/
SYSCALL psend(portid, msg)
int portid;
int msg;
{
char ps;
struct pt *ptptr;
int seq;
struct ptnode *freenode;
disable(ps);
if (isbadport(portid) ||
# ifdef MEMMARK
unmarked(ptmark) ||
# endif
(ptptr=&ports[portid])->ptstate != PTALLOC) {
restore(ps);
return(SYSERR);
}
/* wait for space and verify port is still allocated */
seq = ptptr->ptseq;
if (wait(ptptr->ptssem) == SYSERR
|| ptptr->ptstate != PTALLOC
|| ptptr->ptseq != seq) {
restore(ps);
return(SYSERR);
}
if (ptfree == NULL)
panic("Ports - out of nodes");
freenode = ptfree;
ptfree = freenode->ptnext;
freenode->ptnext = NULL;
freenode->ptmsg = msg;
if (ptptr->pttail == NULL) /* empty queue */
ptptr->pttail = ptptr->pthead = freenode;
else {
(ptptr->pttail)->ptnext = freenode;
ptptr->pttail = freenode;
}
signal(ptptr->ptrsem);
restore(ps);
return(OK);
}
/* putc.c - putc p. 147 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
/*-----------------------------------------------------------------------------
* putc -- write a single character to a device
*-----------------------------------------------------------------------------
*/
putc(descrp, ch)
int descrp;
char ch;
{
struct devsw *devptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
return ((*devptr->dvputc)(devptr,ch));
}